/**
 * @author nam
 */

package csc.fresher.view;

import java.io.IOException;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import csc.fresher.commons.BankingConstant;
import csc.fresher.entity.AccountState;
import csc.fresher.entity.Customer;
import csc.fresher.entity.CustomerAccount;
import csc.fresher.entity.DepositTransaction;
import csc.fresher.entity.SystemUser;
import csc.fresher.entity.TransactionState;
import csc.fresher.entity.TransactionType;
import csc.fresher.service.AccountService;
import csc.fresher.service.DepositAccountService;
import csc.fresher.service.DepositAccountTransactionService;
import csc.fresher.service.SystemUserService;

@Component
@Scope("session")
public class DepositAccountWithdrawFundsManageBean implements Serializable {
	private static final long serialVersionUID = 1L;

	@Autowired
	DepositAccountTransactionService depositAccountTransactionService;
	@Autowired
	DepositAccountService depositAccountService;
	@Autowired
	AccountService accountService;
	@Autowired
	private SystemLoginManageBean systemLoginManageBean;
	@Autowired
	private SystemUserService systemUserService;

	private Customer customer;
	private CustomerAccount customerAccount;
	private DepositTransaction transaction;
	private double withdrawAmount;
	private double balanceAfter;
	private Timestamp transactionTime;
	private SystemUser systemUser;
	private long selectedAccountID;
	
	public Customer getCustomer() {
		return customer;
	}

	public void setCustomer(Customer customer) {
		this.customer = customer;
	}
	
	public void onLoad() {
		
		if(systemLoginManageBean.getSystemUser() == null) {
			try {
				FacesContext.getCurrentInstance().getExternalContext().redirect("/csc_final/templates3/Logon.jsf");
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			systemUser = systemLoginManageBean.getSystemUser();
			List<Long> listrole = systemUserService.getRoleByUserName(systemUser.getUserName());			
			boolean result = checkRole(listrole);
			if(result == false) {
				try {
					FacesContext.getCurrentInstance().getExternalContext().redirect("/csc_final/Group1/AccountManagement.xhtml");
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public boolean checkRole(List<Long> listRole) {
		
		for(int i = 0; i < listRole.size(); i++) {
			if (BankingConstant.ROLE_ACCOUNT_ADMIN == listRole.get(i) || BankingConstant.ROLE_ACCOUNT_SUPPORT == listRole.get(i)){
				return true;
			}
		}		
		return false;
	}

	public String getInfoOfTransaction() {
		FacesContext fc = FacesContext.getCurrentInstance();
	    Map<String,String> params =  fc.getExternalContext().getRequestParameterMap();
	    
	    String strID= params.get("selectedAccountID");
	    try{
	    	this.selectedAccountID  = Long.parseLong(strID);
	    }
	    catch(NumberFormatException e){
	    	FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Null Account"));
			return "";
	    }
		this.customerAccount = depositAccountService.getDepositAccountByDepositAccountID(selectedAccountID);
		this.withdrawAmount = 0;
		if (customerAccount == null) {
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Null Account"));
			return "";
		}
		if (!customerAccount.getAccountState().getState().equals(
				AccountState.ACTIVE.getState())) {
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("This account can't perform transaction!"));
			return "";
		}
		if (customerAccount != null) {
			this.customer = accountService.getCustomerByID(customerAccount
					.getCustomerID());
		}
		return "withdrawFund";
	}

	public String confirmWithdrawTransaction() {
		if(this.withdrawAmount <=0){
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("The transfer money must be larger than 0"));
			return "withdrawFund";
		}
		double afterBalance = customerAccount.getAccountBalance() - this.withdrawAmount;
		if (afterBalance < 0) {
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("This account doesn't have enough money!"));
			return "withdrawFund";
		} else {
			this.setBalanceAfter(afterBalance);
		}
		return "withdrawConfirm";
	}

	public String completeWithdrawTransction(){
		systemUser = systemLoginManageBean.getSystemUser();
		this.transactionTime = new Timestamp(System.currentTimeMillis());
		transaction = new DepositTransaction(withdrawAmount, transactionTime, transactionTime, customerAccount.getAccountBalance(),this.balanceAfter,TransactionType.WITHDRAW, 
				customerAccount.getAccountNumber(), customerAccount.getAccountNumber(), 
				TransactionState.HOLD, customerAccount.getAccountNumber(), systemUser.getSystemUserID(), BankingConstant.DEFAULT_SYSTEM_USER_ID, false,"");
		
		if(depositAccountTransactionService.withdrawFunds(transaction)>0){
			return "withdrawComplete";
		}
		else{
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Transaction fail! Please try again!"));
			return "withdrawConfirm";
		}
		
	}
	
	
	public CustomerAccount getCustomerAccount() {
		return customerAccount;
	}

	public void setCustomerAccount(CustomerAccount customerAccount) {
		this.customerAccount = customerAccount;
	}

	public DepositTransaction getTransaction() {
		return transaction;
	}

	public void setTransaction(DepositTransaction transaction) {
		this.transaction = transaction;
	}

	public double getWithdrawAmount() {
		return withdrawAmount;
	}

	public void setWithdrawAmount(double withdrawAmount) {
		this.withdrawAmount = withdrawAmount;
	}

	public double getBalanceAfter() {
		return balanceAfter;
	}

	public void setBalanceAfter(double balanceAfter) {
		this.balanceAfter = balanceAfter;
	}

	public Timestamp getTransactionTime() {
		return transactionTime;
	}

	public void setTransactionTime(Timestamp transactionTime) {
		this.transactionTime = transactionTime;
	}

	public SystemUser getSystemUser() {
		return systemUser;
	}

	public void setSystemUser(SystemUser systemUser) {
		this.systemUser = systemUser;
	}

	public long getSelectedAccountID() {
		return selectedAccountID;
	}

	public void setSelectedAccountID(long selectedAccountID) {
		this.selectedAccountID = selectedAccountID;
	}

}
